﻿using Fleck;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;

namespace WebSocket
{
    public partial class Form1 : Form ,IDisposable
    {
        //private LocalWebSocketServer localWebSocketServer;
        /// <summary>
        /// WebSocket实例
        /// </summary>
        private WebSocketServer socketServer = null;

        private string url;  //"ws://0.0.0.0:8888";


        /// <summary>
        /// 连接的客户端
        /// </summary>
        private Dictionary<string, IWebSocketConnection> clientList;

        /// <summary>
        /// 要移除的客户端列表
        /// </summary>
        private List<string> removeList;

        public void WebsocketServer_Start()
        {
            try
            {
                if (socketServer == null)
                {
                    socketServer = new WebSocketServer(txtUrl.Text);
                }

                //restart
                socketServer.RestartAfterListenError = true;
                socketServer.Start(ListenWebSocketConnection);
                tb.Text += $"客户端已连接{Environment.NewLine}";
            }
            catch (Exception ex)
            {
                tb.Text = $"Local webSocket server fail to start：{ex.Message}{Environment.NewLine}";
            }
        }

        public void ReStart()
        {
            if (socketServer != null)
            {
                socketServer.Dispose();
                socketServer = null;
            }

            WebsocketServer_Start();
        }

        private void ListenWebSocketConnection(IWebSocketConnection client)
        {
            string clientId = client.ConnectionInfo.Id.ToString();
            client.OnOpen = () =>
            {
                if (clientList == null || clientList.Count == 0)
                {
                    clientList = new Dictionary<string, IWebSocketConnection>();
                }

                if (!clientList.ContainsKey(clientId))
                {
                    clientList.Add(clientId, client);
                }
            };
            client.OnMessage = (message) =>
            {
                Console.WriteLine(message);
                // 确保在UI线程中更新文本框
                Action<string> updateUi = (msg) =>
                {
                    tb.Text += $"{msg}{Environment.NewLine}";
                };

                if (tb.InvokeRequired)
                {
                    tb.Invoke(updateUi, message);
                }
                else
                {
                    updateUi(message);
                }
                //Task task = Broadcast(message);
            };
            client.OnClose = () =>
            {
                if (clientList != null && clientList.Count > 0)
                {
                    clientList.Remove(clientId);
                }
            };
            client.OnPing = (data) =>
            {

            };
        }

        /// <summary>
        /// Broadcast
        /// </summary>
        /// <param name="message"></param>
        public async Task Broadcast(string message)
        {
            //Broadcast to all clients
            if (clientList == null || clientList.Count == 0)
            {
                return;
            }

            removeList = new List<string>();

            foreach (var client in clientList)
            {
                if (client.Value.IsAvailable)
                {
                    await client.Value.Send(message);
                }
                else
                {
                    removeList.Add(client.Key);
                }
            }

            if (removeList != null && removeList.Count > 0)
            {
                removeList.ForEach(clientId =>
                {
                    clientList.Remove(clientId);
                });
            }
        }

        public void Dispose()
        {
            if (socketServer != null)
            {
                socketServer.Dispose();
                socketServer = null;
            }

            clientList = null;

            removeList = null;
        }

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            WebsocketServer_Start();
            button1.Enabled = false;
        }

        private void OnMessage(object sender,string e)
        {
            tb.Text += $"{e}{Environment.NewLine}";
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            Task task = Broadcast(txtSend.Text);
        }
    }
}
